package prefuse.table;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

import javax.swing.*;

import prefuse.*;
import prefuse.action.ActionList;
import prefuse.action.RepaintAction;
import prefuse.action.assignment.ColorAction;
import prefuse.action.assignment.DataShapeAction;
import prefuse.action.layout.AxisLabelLayout;
import prefuse.action.layout.AxisLayout;
import prefuse.controls.FocusControl;
import prefuse.controls.PanControl;
import prefuse.controls.ToolTipControl;
import prefuse.controls.WheelZoomControl;
import prefuse.controls.ZoomControl;
import prefuse.controls.ZoomToFitControl;
import prefuse.data.Table;
import prefuse.gui.InterfaceHandler;
import prefuse.render.AbstractShapeRenderer;
import prefuse.render.AxisRenderer;
import prefuse.render.DefaultRendererFactory;
import prefuse.render.Renderer;
import prefuse.render.RendererFactory;
import prefuse.render.ShapeRenderer;
import prefuse.util.ColorLib;
import prefuse.util.ui.UILib;
import prefuse.vensim.CopyOfReadText;
import prefuse.vensim.ReadText;
import prefuse.vensim.VensimException;
import prefuse.visual.VisualItem;
import prefuse.visual.expression.VisiblePredicate;

public class TableCreater extends Display {
	private static final String group = "data";
	private static ReadText a;
	private static CopyOfReadText ab;
	private static Set<Double> timeList;
	private static String[] timeStringFormat;
	private static String[] timeStringDoubleFormat;
	private static Table table;
	private static InterfaceHandler interfaceHandler;
	
	
	public TableCreater( InterfaceHandler interfaceHand) {
		super(new Visualization());
		interfaceHandler = interfaceHand;
	}

	public  Table generateTable(String txtfile, String key,
			Set<Double> timeList1) throws IOException {
		timeList = timeList1;
		System.out.println("timeList.size()" + timeList.size());
		timeStringFormat = new String[timeList.size()];
		timeStringDoubleFormat = new String[timeList.size()];

		for (Double str : timeList) {
			System.out.println("Double value is : " + str);
		}

		Iterator<Double> it = timeList.iterator();
		int i = 0;
		while (it.hasNext()) {
			double d = it.next();
			if (d == (int) d){
				timeStringFormat[i] = String.format("%d", (int) d);
				timeStringDoubleFormat[i] = String.format("%s", d);
			}
			else{
				timeStringFormat[i] = String.format("%s", d);
				timeStringDoubleFormat[i] = String.format("%s", d);
				}
			i++;
		}

		for(String tempann:timeStringDoubleFormat){
			System.out.println("this is tempAnn: " + tempann);
		}
		
		System.out.println("this is t.length: " + timeStringFormat.length);
		a = new ReadText(txtfile);
		a.searchMap(key, timeStringFormat);

		table = new Table();
		double[] dataText = new double[] {};
		dataText = a.getValue();
		System.out.println("hhhhahahahaha1111"+ Arrays.toString(dataText));
		int tableSize = timeList.size();

		// set up table schema
		table.addColumn("Date", String.class);
		table.addColumn("VariableData", double.class);

		table.addRows(tableSize);

		int j = 0;
		Iterator<Double> it2 = timeList.iterator();
		while (it2.hasNext()) {
			String tempdate = dayTimeToDate((int) Math.rint(it2.next()));
			table.set(j, 0, tempdate);
			table.set(j, 1, dataText[j]);
			j++;
		}

		return table;
	}

	private static String dayTimeToDate(int dayN) {
		int dayNumber = dayN;
		Calendar origin = Calendar.getInstance();
		origin.set(1900, 00, 00); // init a origin calendar.
		origin.add(Calendar.DAY_OF_YEAR, dayNumber);
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		String dateString = format.format(origin.getTime());
		System.out.println("Today is:" + dateString);
		return dateString;

	}

	public  Display createVisualization(Table data) {

		Display display = new Display(m_vis);

		// --------------------------------------------------------------------
		// STEP 1: setup the visualized data

		m_vis.add("data", data);

		// --------------------------------------------------------------------
		// STEP 2: set up renderers for the visual data
		//
		// vis.setRendererFactory(new DefaultRendererFactory(
		// new ShapeRenderer(7)));//the size of the circle

		m_vis.setRendererFactory(new RendererFactory() {
			AbstractShapeRenderer sr = new ShapeRenderer(5);
			Renderer arY = new AxisRenderer(Constants.FAR_LEFT,
					Constants.CENTER);
			Renderer arX = new AxisRenderer(Constants.CENTER,
					Constants.FAR_BOTTOM);

			public Renderer getRenderer(VisualItem item) {
				return item.isInGroup("ylab") ? arY
						: item.isInGroup("xlab") ? arX : sr;
			}
		});

		// --------------------------------------------------------------------
		// STEP 3: create actions to process the visual data

		AxisLayout x_axis = new AxisLayout("data", "Date", Constants.X_AXIS,
				VisiblePredicate.TRUE);
		m_vis.putAction("x", x_axis);
		AxisLayout y_axis = new AxisLayout("data", "VariableData",
				Constants.Y_AXIS, VisiblePredicate.TRUE);
		m_vis.putAction("y", y_axis);

		AxisLabelLayout x_labels = new AxisLabelLayout("xlab", x_axis);// You
																		// can
																		// change
																		// the
																		// spacing
																		// the
																		// minimum
																		// spacing
																		// between
																		// axis
																		// labels
		// public AxisLabelLayout(String group, AxisLayout layout, Rectangle2D
		// bounds, double spacing)

		AxisLabelLayout y_labels = new AxisLabelLayout("ylab", y_axis);

		ColorAction color = new ColorAction("data", VisualItem.FILLCOLOR,
				ColorLib.rgb(100, 100, 255));

		ActionList draw = new ActionList();
		draw.add(x_axis); // draw point
		draw.add(y_axis); // draw point
		draw.add(x_labels);
		draw.add(y_labels);
		draw.add(color);
		// draw.add(shape);
		draw.add(new RepaintAction());
		m_vis.putAction("draw", draw);
		ActionList repaint = new ActionList();
		repaint.add(new RepaintAction());
		m_vis.putAction("repaint", repaint);
		// --------------------------------------------------------------------
		// STEP 4: set up a display and controls
	//	display.setHighQuality(true);
		display.setSize(500, 300);
		display.addControlListener(new ZoomToFitControl());
		display.addControlListener(new ZoomControl());
		display.addControlListener(new WheelZoomControl());
		display.addControlListener(new PanControl());
		
	//	display.setBorder(BorderFactory.createEmptyBorder(15, 30, 15, 30));

		// --------------------------------------------------------------------
		// STEP 5: launching the visualization
		m_vis.run("draw");

		return display;
	}
	
	private Table getTable(){
		return table;
	}
	public static void axisUpdateAction( TableCreater sp, 
			 JComboBox axisComboBox, 
			 String axisFieldName,  String axisLabelFieldName) {
		Visualization vis = sp.getVisualization();
		Table t = (Table)sp.getVisualization().getSourceData(group);
		System.out.println("If table is null?   " + (t==null));
		System.out.println("if sp is null"+ (sp==null));
		AxisLabelLayout labels = (AxisLabelLayout)vis.getAction(axisLabelFieldName);
		AxisLayout axis = (AxisLayout)vis.getAction(axisFieldName);
		String dataField = (String)axisComboBox.getSelectedItem();
		
	//	Table t = sp.getTable();
		
	//	Table t = (Table)vis.getSourceData("data");
	//	boolean hasEnoughElement = t.getColumn(dataField).canGetDouble();
	
	
//did table change on 13/07/2013
		
		try {
			try {
				System.out.println("this is dataField: "+ dataField);
				interfaceHandler.setVariable(dataField);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("this is dataField123: "+ dataField);
			System.out.println("this is timeStringFormat: "+ timeStringFormat.length);
			ab = new CopyOfReadText(interfaceHandler,dataField);
			ab.searchMap(dataField, timeStringDoubleFormat);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			
		}catch (NullPointerException e) {
			// TODO Auto-generated catch block	
			e.printStackTrace();
		//	JOptionPane.showMessageDialog(null, "The variable does not have enough values","No enough values", JOptionPane.INFORMATION_MESSAGE);
		}
		double[] dataText = new double[] {};
		dataText = ab.getValue();
		System.out.println("hhhhahahahahawawawa"+ Arrays.toString(dataText));
		System.out.println("hhhhahahahahawawawa"+ dataText.length);
		
		int j = 0;
		Iterator<Double> it2 = timeList.iterator();
		while (it2.hasNext()) {
			String tempdate = dayTimeToDate((int) Math.rint(it2.next()));
			System.out.println("hhhhahahahaha"+ (t==null));
			t.set(j, 0, tempdate);
			t.set(j, 1, dataText[j]);
			j++;
		}
		
		System.out.println("if axis is null? " + (axis==null));
//		axis.setDataField(dataField);
//		if( hasEnoughElement ) {
			// need to set range model to null to force recalculationd
//			labels.setRangeModel(null);
//			axis.setDataType(Constants.NUMERICAL);
//		} else {     // completely untested with derived columns
//			axis.setDataType(Constants.ORDINAL);
//			labels.setRangeModel(null);
	//	} 

		vis.run("draw");
	}
	
	public static JToolBar getEncodingToolbar(final TableCreater sp,String[] varNames
			) throws VensimException{
	
	//	Table t2 = sp.getTable();
	//	System.out.println("If table is null?   " + (t==null));
	//	System.out.println("If table2 is null?   " + (t2==null));


		 final JComboBox combo = new JComboBox(varNames);

		combo.setPreferredSize(new Dimension(200, 20));

	

		
		combo.setEditable(false);
		combo.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {

//				JComboBox comboBox = (JComboBox) event.getSource();
//				String newSelected = (String) comboBox.getSelectedItem();
				try {
					// System.out.println("I am in here  = " + newSelected);
					// createTable(newSelected);
					// fillComboBox();
//					Set<Double> timeList = new HashSet<Double>();
//					timeList.add(0.0);
//					timeList.add(1.0);
//					timeList.add(2.0);
//					timeList.add(3.0);
//					timeList.add(4.0);
//					
//					Table table = CopyOfTableCreater.generateTable("C:\\tmp\\ann880Test1.txt",
//							newSelected, timeList);
//					final Display display = createVisualization(table);
//					AxisLayout xaxis = (AxisLayout)display.getVisualization().getAction("x");
//					System.out.println("Selected xaxis  = " + xaxis.toString());
					axisUpdateAction(sp, combo, "y", "ylab");
					
			//		System.out.println("Selected varName  = " + "123456");
				
				//	Box box = new Box(BoxLayout.Y_AXIS);
					
				//	box.add(display);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		//		System.out.println("Selected Item  = " + newSelected);
			}
		});
		int spacing = 10;
		JToolBar toolbar = new JToolBar();
		toolbar.add(combo);
		toolbar.add(Box.createHorizontalStrut(2*spacing));
		return toolbar;
	} 

	public static JFrame createAndShowGUI(JComponent display, String title) {
		final JFrame frame = new JFrame();

		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setTitle(title);
		frame.setLocation(700, 10);
		frame.getContentPane().add(display);
		frame.pack();
		frame.setVisible(true);

		return frame;

	}
	
//	public Box getBox(final CopyOfTableCreater sp){
//		Box box = new Box(BoxLayout.Y_AXIS);
//    	 box.add(getEncodingToolbar(sp));
//    	 box.add(display);
//	}

	private static final long serialVersionUID = 1L;

	public static void main(String[] args) throws IOException, VensimException {

		JFrame frame = new JFrame("DecisionTreeView");
		final Set<Double> timeList = new HashSet<Double>();
		timeList.add(0.0);
		timeList.add(1.0);
		timeList.add(2.0);
		timeList.add(3.0);
		timeList.add(4.0);

		
	//	final TableCreater sp = new TableCreater();
//		final Table table = sp.generateTable("C:\\tmp\\Test.txt",
//				"NegativeOfCumulativeWNVSymptomaticCases", timeList);
//		final JComponent display = sp.createVisualization(table);
//		Box box = new Box(BoxLayout.Y_AXIS);
//		box.add(combo);
//		box.add(display);

//		JPanel jRightUpPanel;
//		jRightUpPanel = new JPanel();
//		jRightUpPanel.add(box);
		
		String vensimLib = "VenDLL32";
		String modelLocation = "C:\\tmp\\WNVDecisionTree.vpm";
		
//		VensimHelp vensimController = new VensimHelp(vensimLib, modelLocation);
//		Locale.setDefault(Locale.US);
//		UILib.setPlatformLookAndFeel();
//		String varNames[] = vensimController.loadModelVarName();
//		JToolBar toolbar = getEncodingToolbar(sp,varNames);
		// String selected = (String) combo.getSelectedItem();

		
		// javax.swing.SwingUtilities.invokeLater(new Runnable() {
		// public void run() {
		// createAndShowGUI(display,"ann");
		// }
		// });

	//	frame.getContentPane().add(toolbar);
		
//		frame.getContentPane().add(toolbar, BorderLayout.NORTH);
//		frame.getContentPane().add(display, BorderLayout.CENTER);
//		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//		
		
		frame.pack();
		frame.setVisible(true);
	}

}
